import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# 中文和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def visualize_riemann(f, a, b, n=10):
    """
    可视化黎曼和逼近曲边梯形面积的过程
    """
    x = np.linspace(a, b, 1000)
    y = f(x)
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
    
    # 左图：函数曲线和分割示意
    ax1.plot(x, y, 'b-', linewidth=2, label='y = f(x)')
    ax1.set_xlabel('x')
    ax1.set_ylabel('y')
    ax1.set_title('曲边梯形示意图')
    ax1.grid(True, alpha=0.3)
    ax1.legend()
    
    # 右图：黎曼和可视化
    x_divisions = np.linspace(a, b, n+1)
    ax2.plot(x, y, 'b-', linewidth=2, label='y = f(x)')
    
    # 计算中点黎曼和
    riemann_sum = 0
    for i in range(n):
        x_left = x_divisions[i]
        x_right = x_divisions[i+1]
        x_mid = (x_left + x_right) / 2
        y_mid = f(x_mid)
        width = x_right - x_left
        
        # 添加矩形
        rect = Rectangle((x_left, 0), width, y_mid, 
                        alpha=0.3, color='red')
        ax2.add_patch(rect)
        
        riemann_sum += y_mid * width
        
    ax2.set_xlabel('x')
    ax2.set_ylabel('y')
    ax2.set_title(f'黎曼和逼近 (n={n}, 面积近似值: {riemann_sum:.4f})')
    ax2.grid(True, alpha=0.3)
    ax2.legend()
    
    plt.tight_layout()
    plt.show()
    
    return riemann_sum

# 示例：计算 y = x² 在 [0, 1] 上的积分
def f_example(x):
    return x**2

# 可视化不同分割精细度的逼近效果
for n in [5, 10, 20]:
    approximate_area = visualize_riemann(f_example, 0, 1, n)
    theoretical_area = 1/3
    print(f"n={n}: 近似面积={approximate_area:.4f}, 误差={abs(approximate_area - theoretical_area):.4f}")